<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>防抖</title>
</head>
<body>
    <input type="text" id="input" />
</body>
<script>
    let inputEle = document.getElementById('input')


    // timer会造成全局变量污染，导致内存泄露
    let timer = null
    function debounceO(fun, delay, ...args){
        clearTimeout(timer)
        const that = this
        timer = setTimeout(()=>{
            fun.apply(that,args)
        }, delay)    
    }

    // inputEle.oninput = (e)=>{
    //     debounceO((data)=>console.log(data), 500, e.target.value)
    // }

    // 避免全局变量污染，采用闭包方式封装
    function debounce(fun, delay) {
        let timer
        return function(...args){                        
            const that = this
            clearTimeout(timer)
            timer = setTimeout(()=>{
                fun.apply(that,args)
            }, delay)            
        }
    }
    /*
        外部函数就用来调用一次，timer也只会初始化一次，目的就在于将timer变成局部变量，
        外部函数一调用，随即产生了闭包，内部函数中所使用的timer便一直会保存在内存中，
        不会随着外部函数的执行完成而被释放回收。
        内部函数就是事件处理函数，每次触发事件，就会触发这个函数，
        里面的timer获取和修改的也一直是那个内存中的timer。
        因为timer不是全局变量，避免了全局变量污染，因为闭包，timer又可以一直保存在内存中。
    */
    let fn = debounce((data)=>console.log(data), 500)
    inputEle.oninput = (e)=>{
        console.log('触发input了')
        fn(e.target.value)
    }


    /*
        总结：
            防抖：
                当触发事件时，将等待一定时间后再执行事件处理函数；
                如果在这段时间内再次触发该事件，则重新开始计时，继续延迟事件处理函数的执行，
                直到停止一段时间没有触发该事件后才会执行事件处理函数。
            个人认为，使用全局变量和使用闭包方式造成的影响没有什么区别，两者都会造成内存泄漏。
            采用闭包的优点在于利于封装函数，而全局变量方式无法封装函数，因为它始终在函数的外面。
    */



    /*  要始终记住它的用法，这个debounce函数就是为了将timer定义在函数中成为局部变量，
        内部函数就是事件处理函数，用来响应事件处理的，只因为事件处理函数中用到了setTimeout定时器，
        需要一个定时器id，不想使用全局变量存储这个id，所以外面又包了一个函数用来定义。
    */
    
</script>
</html>